package org.fhnw.aigs.server.common; import org.fhnw.aigs.server.gui.StopServerAction; import org.fhnw.aigs.server.gui.StartServerAction; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.fhnw.aigs.commons.Game; import org.fhnw.aigs.commons.Player; import org.fhnw.aigs.server.communication.ServerCommunication; import org.fhnw.aigs.server.gameHandling.GameLoader; import org.fhnw.aigs.server.gameHandling.GameManager; import org.fhnw.aigs.server.gameHandling.RecompileClassesAction; /** * This class is responsible for console input when the server is run in * console mode.<br> * v1.0 Initial release<br> * v1.1 Functional changes<br> * v1.2 Functional changes<br> * v1.3 Changes of logging * @author Matthias Stöckli (v1.0) * @version 1.3 (Raphael Stoeckli, 24.02.2015) */ public class AIGSConsoleHandler { /** * Scanner for user input. */ Scanner scanner; /** * Contains the current user input as a string. */ String currentInput; /** * Create a new instance of the AIGSConsoleHandler and initialize the scanner. * Use a new line as delimiter. */ public AIGSConsoleHandler(){ scanner = new Scanner(System.in); scanner.useDelimiter("\n"); } /** * Waits for user input (console commands) and processes it. */ public void runInputLoop(){ while(true){ currentInput = scanner.next().trim(); // If the user types in "exit", the server will // shut down, "help" will show which console commands can be used, // "recompile" will terminate all games and recompile/reload the games, // "list" prints out a list of all the games and "terminate" // ends a game. // "start" and "stop" are starting or stopping the service. // "games" shows a list of installed games on the server if(currentInput.startsWith("exit")){ shutdownServer(); }else if(currentInput.startsWith("start")){ startServer(); } else if(currentInput.startsWith("stop")){ stopServer(); } else if(currentInput.startsWith("games")){ listAvailableGames(); } else if(currentInput.startsWith("logs")){ showLogs(); }else if(currentInput.startsWith("help")){ showHelp(); }else if(currentInput.startsWith("recompile")){ recompileClasses(); }else if(currentInput.startsWith("list")){ listActiveGames(); }else if(currentInput.startsWith("terminate")){ terminateGame(currentInput); } } } /** * Method to start the server * @since v1.1 */ private void startServer() { System.out.println("Starting server..."); StartServerAction action = new StartServerAction(); if (ServerCommunication.getInstance().getRunState() == true) { System.out.println("Server allready running. user 'stop' command first to restart"); return; } else { action.startServer(); System.out.println("Server started"); } } /** * Method to stop the service (no shutdown) * @since v1.1 */ private void stopServer() { System.out.println("Stopping server..."); StopServerAction action = new StopServerAction(); action.stopServer(); System.out.println("Server stopped"); } /** * Show list of all installed games * @since v1.1 */ private void listAvailableGames() { ArrayList<String> games = GameLoader.getInstalledGames(); //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "List installed games..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "List installed games..."); System.out.println("Installed games:\r\n----------------------"); for(String game : games) { System.out.println(game); } } /** * Shuts down the server. */ private void shutdownServer() { //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "Shut down server..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "Shut down server..."); System.exit(0); } /** * Opens the logs folder. */ private void showLogs() { //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "Show logs folder..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "Show logs folder..."); new ShowLogsAction().showLogs(); } /** * Show all possible console commands. */ private void showHelp() { System.out.println("You can type the following commands:\r\n"); System.out.println("start: Start the service of the server.\r\n"); System.out.println("stop: Stop the service of the server.\r\n"); System.out.println("exit: Shut down server.\r\n"); System.out.println("logs: Open the logs folder.\r\n"); System.out.println("recompile: Stops all games and recompiles\reloads the game chars. \r\n"); System.out.println("list: Show a list of all waiting or running games.\r\n"); System.out.println("games: Show a list of all installed games on the server.\r\n"); System.out.println("Terminate [gameID]: Stops the game with the specified" + "game ID. Use 'all' to termiante all games. \r\n"); } /** * Terminate all games and reload classes. */ private void recompileClasses() { //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "Recompile and reload classes..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "Recompile and reload classes..."); new RecompileClassesAction().recompileClasses(); new RecompileClassesAction().reloadClasses(); } /** * List all waiting and running games. */ private void listActiveGames() { //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "List waiting and active games..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "List waiting and active games..."); System.out.println("Waiting games:\r\n----------------------"); for(Game game : GameManager.waitingGames){ System.out.println(game.toString()); System.out.println("Participants:"); for(Player player : game.getPlayers()){ System.out.println(player.toString()); } System.out.println("\r\n-----"); } System.out.println("Running games:\r\n----------------------"); for(Game game : GameManager.runningGames){ System.out.println(game.toString()); System.out.println("Participants:"); for(Player player : game.getPlayers()){ System.out.println(player.toString()); } System.out.println("\r\n-----"); } } /** * Terminates the specified game using it's ID. * @param terminateString The input string. */ private void terminateGame(String terminateString) { Pattern p = Pattern.compile("(terminate\\x20)(.+|\\w+|\\W+)?"); Matcher m = p.matcher(terminateString); if (m.find()) { String toBeTerminated = m.group(2); if(toBeTerminated.equals("all")){ terminateAllGames(); } else{ terminateSpecifiedGame(toBeTerminated); } } } /** * Terminates all waiting and running games. */ private void terminateAllGames() { //LOG//Logger.getLogger(AIGSConsoleHandler.class.getName()).log(Level.INFO, "Terminate all games..."); LogRouter.log(AIGSConsoleHandler.class.getName(), LoggingLevel.system, "Terminate all games..."); for(Game game : GameManager.waitingGames){ GameManager.terminateGame(game, "Termination requested by administrator."); } for(Game game : GameManager.runningGames){ GameManager.terminateGame(game, "Termination requested by administrator."); } } /** * Terminates a single game. * @param toBeTerminated The ID of the game which will be terminated. */ private void terminateSpecifiedGame(String toBeTerminated) { try{ int id = Integer.parseInt(toBeTerminated); for(int i = 0; i < GameManager.waitingGames.size(); i++){ Game game = GameManager.waitingGames.get(i); if(game.getId() == id){ GameManager.terminateGame(game, "Termination requested by administrator."); } } for (int i = 0; i < GameManager.runningGames.size(); i++) { Game game = GameManager.runningGames.get(i); if (game.getId() == id) { GameManager.terminateGame(game, "Termination requested by administrator."); } } }catch(NumberFormatException ex){ System.out.println("Invalid input. Either type the id of a game" + "or type 'all' to terminate all games. In order to get" + "a list of all games, type 'list'"); } catch (Exception ex) // All other exceptions { System.out.println("An unknown error occurred: " + ex.getMessage()); } } }